package com.glink.manage.ftp;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.xssf.streaming.SXSSFDrawing;
import org.apache.poi.xssf.streaming.SXSSFPicture;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
@Slf4j
public class FTPUtils {

    @Resource
    private FTPClientPool ftpClientPool;


    @Autowired(required = false)
    private FTPClientFactory ftpClientFactory;

    private static final String BASE_DIR = "/";


    public void returnClient(SSLSessionReuseFTPSClient client) {
        this.ftpClientPool.returnObject(client);
    }


    public SSLSessionReuseFTPSClient getSslSessionReuseFTPSClient() throws Exception {
        return this.ftpClientPool.borrowObject();
    }

    public SSLSessionReuseFTPSClient createNewFTPSClient() throws Exception {
        return this.ftpClientPool.reconnect();
    }


    public <T> T execute(FTPExecutor<T> executor) throws Exception {
        SSLSessionReuseFTPSClient client = null;
        try {
            client = getSslSessionReuseFTPSClient();
            if (client != null) {

                String baseDir = client.printWorkingDirectory();
                if (!"/".equals(baseDir)) {
                    client.changeWorkingDirectory("/");
                }
                return executor.execute(client);
            }
            throw new FTPException("FTP连接池获取连接失败");
        } finally {

            if (client != null) {

                client.changeWorkingDirectory("/");
                returnClient(client);
            }
        }
    }

    public String findFileSize(String ftpPath, String ftpName) throws IOException {
        log.info("ftp downLoadFile start,ftpPath:{},ftpName:{}", ftpPath, ftpName);
        if (!ftpPath.startsWith(File.separator)) {
            ftpPath = File.separator + ftpPath;
        }

        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        String baseDir = "";
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            if (sslSessionReuseFTPSClient == null) {
                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
            }

            baseDir = sslSessionReuseFTPSClient.printWorkingDirectory();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpPath);
            String size = sslSessionReuseFTPSClient.getSize(ftpName);
            sslSessionReuseFTPSClient.changeWorkingDirectory(baseDir);
            return size;
        } catch (Exception e) {
            if(sslSessionReuseFTPSClient != null){
                try {
                    sslSessionReuseFTPSClient.disconnect();
                } catch (IOException ex) {
                    log.error("sslSessionReuseFTPSClient close ", ex);
                }
            }
            log.error("ftp downLoadFile fail,ftpPath:{},ftpName:{},message:{}", ftpPath, ftpName, e.getMessage());
            return null;
        } finally {
            returnClient(sslSessionReuseFTPSClient);
        }
    }

    public boolean deleteFile(String ftpFilePath) throws Exception {
        if (StringUtils.isBlank(ftpFilePath)) {
            return false;
        }
        String finalFtpFilePath = convert2FTPCharset(ftpFilePath);
        return execute(client -> Boolean.valueOf(client.deleteFile(finalFtpFilePath))).booleanValue();
    }


    public boolean downLoadFileTest(String localFullPath, String ftpPath, String fileName) throws IOException {
        log.info("ftp downLoadFile start,localPath:{},ftpPath:{},fileName:{}", localFullPath, ftpPath, fileName);
        if (!ftpPath.startsWith(File.separator)) {
            ftpPath = File.separator + ftpPath;
        }
        File localFileDir = new File(localFullPath);
        if (Objects.nonNull(localFileDir.getParentFile()) && (!localFileDir.getParentFile().exists() || !localFileDir.getParentFile().isDirectory())) {
            localFileDir.getParentFile().mkdirs();
            localFileDir.createNewFile();
        }

        File localFile = new File(localFullPath);
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        String baseDir = "";
        try (OutputStream is = new FileOutputStream(localFile, true)) {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            if (sslSessionReuseFTPSClient == null) {
                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
            }

            baseDir = sslSessionReuseFTPSClient.printWorkingDirectory();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpPath);
            sslSessionReuseFTPSClient.setRestartOffset(500);
            boolean status = sslSessionReuseFTPSClient.retrieveFile(new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"), is);

            sslSessionReuseFTPSClient.changeWorkingDirectory(baseDir);
            return status;
        } catch (Exception e) {
            if(sslSessionReuseFTPSClient != null){
                try {
                    sslSessionReuseFTPSClient.disconnect();
                } catch (IOException ex) {
                    log.error("sslSessionReuseFTPSClient close ", ex);
                }
            }
            log.error("ftp downLoadFile fail,localPath:{},ftpPath:{},fileName:{},message:{}", localFullPath, ftpPath, fileName, e.getMessage());
            return false;
        } finally {

            returnClient(sslSessionReuseFTPSClient);
        }
    }

    public InputStream downLoadFileStream(String ftpPath, String fileName, Long startOffset) throws IOException {
        log.info("ftp downLoadFile start,ftpPath:{},fileName:{}", ftpPath, fileName);
        if (!ftpPath.startsWith(File.separator)) {
            ftpPath = File.separator + ftpPath;
        }

        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        String baseDir = "";
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            if (sslSessionReuseFTPSClient == null) {
                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
            }

            baseDir = sslSessionReuseFTPSClient.printWorkingDirectory();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpPath);
            if(Objects.nonNull(startOffset)){
                sslSessionReuseFTPSClient.setRestartOffset(startOffset);    
            }
            InputStream inputStream = sslSessionReuseFTPSClient.retrieveFileStream(new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"));
            sslSessionReuseFTPSClient.changeWorkingDirectory(baseDir);
            return inputStream;
        } catch (Exception e) {
            if(sslSessionReuseFTPSClient != null){
                try {
                    sslSessionReuseFTPSClient.disconnect();
                } catch (IOException ex) {
                    log.error("sslSessionReuseFTPSClient close ", ex);
                }
            }
            log.error("ftp downLoadFile fail,ftpPath:{},fileName:{},message:{}", ftpPath, fileName, e.getMessage());
            return null;
        } finally {

            returnClient(sslSessionReuseFTPSClient);
        }
    }
    
    public boolean downLoadFile(String localFullPath, String ftpPath, String fileName) throws IOException {
        log.info("ftp downLoadFile start,localPath:{},ftpPath:{},fileName:{}", localFullPath, ftpPath, fileName);
        if (!ftpPath.startsWith(File.separator)) {
            ftpPath = File.separator + ftpPath;
        }
        File localFileDir = new File(localFullPath);
        if (Objects.nonNull(localFileDir.getParentFile()) && (!localFileDir.getParentFile().exists() || !localFileDir.getParentFile().isDirectory())) {
            localFileDir.getParentFile().mkdirs();
            localFileDir.createNewFile();
        }

        File localFile = new File(localFullPath);
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        String baseDir = "";
        try (OutputStream is = Files.newOutputStream(localFile.toPath(), new java.nio.file.OpenOption[0])) {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            if (sslSessionReuseFTPSClient == null) {
                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
            }

            baseDir = sslSessionReuseFTPSClient.printWorkingDirectory();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpPath);
            boolean status = sslSessionReuseFTPSClient.retrieveFile(new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"), is);

            sslSessionReuseFTPSClient.changeWorkingDirectory(baseDir);
            return status;
        } catch (Exception e) {
            if(sslSessionReuseFTPSClient != null){
                try {
                    sslSessionReuseFTPSClient.disconnect();
                } catch (IOException ex) {
                    log.error("sslSessionReuseFTPSClient close ", ex);
                }    
            }
            log.error("ftp downLoadFile fail,localPath:{},ftpPath:{},fileName:{},message:{}", localFullPath, ftpPath, fileName, e.getMessage());
            return false;
        } finally {

            returnClient(sslSessionReuseFTPSClient);
        }
    }

//    public boolean downLoadFile(String localPath, String ftpPath, String fileName) {
//        log.info("ftp downLoadFile start,localPath:{},ftpPath:{},fileName:{}", new Object[]{localPath, ftpPath, fileName});
//        if (!localPath.endsWith(File.separator)) {
//            localPath = localPath + File.separator;
//        }
//        if (!ftpPath.startsWith(File.separator)) {
//            ftpPath = File.separator + ftpPath;
//        }
//        File localFileDir = new File(localPath);
//        if (!localFileDir.exists() || !localFileDir.isDirectory()) {
//            localFileDir.mkdirs();
//        }
//
//        File localFile = new File(localPath + fileName);
//        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
//        try (OutputStream is = Files.newOutputStream(localFile.toPath(), new java.nio.file.OpenOption[0])) {
//            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
//            if (sslSessionReuseFTPSClient == null) {
//                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
//            }
//            sslSessionReuseFTPSClient.changeWorkingDirectory(ftpPath);
//            boolean status = sslSessionReuseFTPSClient.retrieveFile(fileName, is);
//            returnClient(sslSessionReuseFTPSClient);
//            return status;
//        } catch (Exception e) {
//            if(sslSessionReuseFTPSClient != null){
//                try {
//                    sslSessionReuseFTPSClient.disconnect();
//                } catch (IOException ex) {
//                    log.error("sslSessionReuseFTPSClient close ", ex);
//                }    
//            }
//            log.error("ftp downLoadFile fail,localPath:{},ftpPath:{},fileName:{},message:{}", new Object[]{localPath, ftpPath, fileName, e.getMessage()});
//            return false;
//        } finally {
//        }
//    }


    public byte[] getFtpFileByte(String filePath) throws Exception {
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
        log.info("获取ftpclient成功{}", sslSessionReuseFTPSClient.toString());
        InputStream inputStream = null;
        try {
            inputStream = sslSessionReuseFTPSClient.retrieveFileStream(new String(filePath.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"));
            if (ObjectUtil.isNotNull(inputStream)) {
                byte[] bytes = IOUtils.toByteArray(inputStream);
                inputStream.close();
                sslSessionReuseFTPSClient.completePendingCommand();
                log.info("从ftp读取文件{} 成功 -> {} ", filePath, sslSessionReuseFTPSClient);
                returnClient(sslSessionReuseFTPSClient);
                return bytes;
            }
            log.info("sslSessionReuseFTPSClient {}", Boolean.valueOf((sslSessionReuseFTPSClient == null)));
            log.info("{} inputStream is null ftp{} code{} -->{} ", new Object[]{filePath, sslSessionReuseFTPSClient, Integer.valueOf(sslSessionReuseFTPSClient.getReplyCode()), sslSessionReuseFTPSClient.getReplyString()});
            sslSessionReuseFTPSClient.disconnect();

        } catch (Exception ex) {
            if (Objects.nonNull(sslSessionReuseFTPSClient)) {
                sslSessionReuseFTPSClient.disconnect();
            }
            log.error("ftp 读取异常:" + sslSessionReuseFTPSClient, ex);
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
        }
        return null;
    }


    public String getFtpSmallFilePath(String filePath) {
        String[] split = filePath.split("\\.");
        if (!filePath.startsWith("/")) {
            return "/" + split[0] + "_small." + split[split.length - 1].toLowerCase();
        }
        return split[0] + "_small." + split[split.length - 1].toLowerCase();
    }


    public String getFtpResultFilePath(String filePath) {
        String[] split = filePath.split("\\.");
        if (!filePath.startsWith("/")) {
            return "/" + split[0] + "_result." + split[split.length - 1].toLowerCase();
        }
        return split[0] + "_result." + split[split.length - 1].toLowerCase();
    }


    public void inputStream(SSLSessionReuseFTPSClient sslSessionReuseFTPSClient, SXSSFWorkbook workbook, SXSSFSheet sheet, String filePath, int excelRowNum) {
        InputStream inputStream = null;
        try {
            inputStream = sslSessionReuseFTPSClient.retrieveFileStream(filePath);
            if (null != inputStream) {
                BufferedImage read = ImageIO.read(inputStream);
                ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
                ImageIO.write(read, "jpg", byteArrayOut);
                SXSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
                XSSFClientAnchor xssfClientAnchor = new XSSFClientAnchor(127000, 127000, -127000, -127000, 11, excelRowNum, 12, excelRowNum + 1);

                SXSSFPicture sXSSFPicture = drawingPatriarch.createPicture((ClientAnchor) xssfClientAnchor, workbook
                        .addPicture(byteArrayOut.toByteArray(), 5));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        if (inputStream != null) {
            try {
                inputStream.close();
                sslSessionReuseFTPSClient.completePendingCommand();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        FTPUtils ftpUtils = new FTPUtils();
        ftpUtils.uploadFile("test", "E:\\桌面\\1719910929285.xlsx");
    }

    public boolean uploadFile(String ftpFileName, MultipartFile multipartFile) {
        InputStream inputStream;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            log.error("从multipartFile获取文件流失败", e);
            return false;
        }
        return uploadFile(ftpFileName, inputStream);
    }


    public boolean uploadFile(String ftpFilePath, InputStream inputStream) {
        boolean success = false;
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = createNewFTPSClient();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpFilePath);

            log.info(ftpFilePath + "开始上传.....");

            log.info("FTP的工作目录为---------:" + sslSessionReuseFTPSClient.printWorkingDirectory());

            String fileName = ftpFilePath.substring(ftpFilePath.lastIndexOf(File.separator) + 1);
            success = sslSessionReuseFTPSClient.storeFile(convert2FTPCharset(fileName), inputStream);
            log.info(ftpFilePath + "上传结果：" + success);
        } catch (Exception e) {
            log.info("------------上传异常", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (Objects.nonNull(sslSessionReuseFTPSClient)) {
                try {
                    sslSessionReuseFTPSClient.disconnect();
                } catch (IOException e) {
                    log.info("ftpclient 关闭 异常", e);
                }
            }
        }
        return success;
    }


    public boolean uploadFile(String ftpFilePath, byte[] bytes) {
        InputStream inputStream = new ByteArrayInputStream(bytes);
        return uploadFile(ftpFilePath, inputStream);
    }


    public boolean uploadFile(String ftpFileName, String localFileName) {
        boolean success = false;
        BufferedInputStream inputStream = null;
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpFileName);
            File localFile = new File(localFileName);
            inputStream = new BufferedInputStream(new FileInputStream(localFile));
            log.info(localFile.getName() + "开始上传.....");

            log.info("FTP的工作目录为---------:" + sslSessionReuseFTPSClient.printWorkingDirectory());

            String fileName = ftpFileName.substring(ftpFileName.lastIndexOf(File.separator) + 1);
            success = sslSessionReuseFTPSClient.storeFile(convert2FTPCharset(fileName), inputStream);
            if (success == true) {
                log.info(localFile.getName() + "上传成功");
            } else {
                log.info(localFile.getName() + "上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("------------上传失败" + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            returnClient(sslSessionReuseFTPSClient);
        }
        return success;
    }


    public boolean rename(String fromFile, String toFile) {
        boolean success = false;
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = createNewFTPSClient();
            String newFromFile = convert2FTPCharset(fromFile);
            String newtoFile = convert2FTPCharset(toFile);
            success = sslSessionReuseFTPSClient.rename(newFromFile, newtoFile);
            return success;
        } catch (Exception e) {
            e.printStackTrace();

            return false;
        }
    }


    public boolean moveFile(String fromFile, String toFile) {
        boolean success = false;
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = createNewFTPSClient();
            changeWorkingDirectory(sslSessionReuseFTPSClient, toFile);
            String newFromFile = convert2FTPCharset(fromFile);
            String newtoFile = convert2FTPCharset(toFile);
            sslSessionReuseFTPSClient.setFileType(2);
            success = sslSessionReuseFTPSClient.rename(newFromFile, newtoFile);
            return success;
        } catch (Exception e) {
            e.printStackTrace();

            return false;
        }
    }


    public synchronized void changeWorkingDirectory(SSLSessionReuseFTPSClient sslSessionReuseFTPSClient, String ftpFilePath) {
        try {
            String ftpFileName = ftpFilePath.replaceAll("\\\\", "/");
            String directory = ftpFileName.substring(0, ftpFileName.lastIndexOf("/"));
            String d = convert2FTPCharset(directory);
            if (!sslSessionReuseFTPSClient.changeWorkingDirectory(d)) {
                String[] arr = d.split("/");
                String initDirectory = sslSessionReuseFTPSClient.printWorkingDirectory();
                log.info("初始路径：" + initDirectory);

                for (String s : arr) {
                    d = convert2FTPCharset(s);
                    Boolean aBoolean = Boolean.valueOf(sslSessionReuseFTPSClient.changeWorkingDirectory(d));
                    log.info("切换目录1" + d + ";" + aBoolean);
                    if (!"".equals(d) && !aBoolean.booleanValue()) {


                        Boolean bBoolean = Boolean.valueOf(sslSessionReuseFTPSClient.makeDirectory(d));
                        log.info("创建目录" + d + ";" + bBoolean);
                        if (bBoolean.booleanValue()) {
                            Boolean cBoolean = Boolean.valueOf(sslSessionReuseFTPSClient.changeWorkingDirectory(d));
                            log.info("切换目录2" + d + ";" + cBoolean);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void closeConnection(SSLSessionReuseFTPSClient sslSessionReuseFTPSClient) {
        log.info("【关闭文件服务器连接】");
        try {
            if (sslSessionReuseFTPSClient != null && sslSessionReuseFTPSClient.isConnected()) {
                log.info("ftpClient连接已关闭4");
                sslSessionReuseFTPSClient.disconnect();
                log.info("ftpClient连接已关闭5");
            }
        } catch (IOException e) {
            log.error("【关闭连接失败】", e);
            throw new RuntimeException("关闭连接失败");
        }
    }


    public boolean existFtpFile(String filePath) throws Exception {
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();

        String substring = filePath.substring(0, filePath.lastIndexOf("/"));

        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
        sslSessionReuseFTPSClient.changeWorkingDirectory(substring);
        String[] strings = sslSessionReuseFTPSClient.listNames();
        returnClient(sslSessionReuseFTPSClient);
        if (strings != null && strings.length > 0) {
            List<String> collect = (List<String>) Arrays.<String>stream(strings).filter(i -> i.equals(fileName)).collect(Collectors.toList());
            return (collect.size() > 0);
        }
        return false;
    }


    private static String convert2FTPCharset(String str) {
        if (str == null) {
            return null;
        }
        return new String(str.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
    }


    public boolean uploadToRemoteFTP(String ftpFileName, InputStream inputStream) {
        if (this.ftpClientFactory == null) {
            log.error("远程系统FTP配置缺失，上传文件失败。");
            return false;
        }
        SSLSessionReuseFTPSClient remoteFTPClient = null;
        try {
            remoteFTPClient = this.ftpClientFactory.createRemoteFTPClient();
            changeWorkingDirectory(remoteFTPClient, ftpFileName);
            log.debug("远程系统FTP的工作目录为{}", remoteFTPClient.printWorkingDirectory());
            String fileName = ftpFileName.substring(ftpFileName.lastIndexOf("/") + 1);
            boolean success = remoteFTPClient.storeFile(convert2FTPCharset(fileName), inputStream);
            log.info("{}上传" + (success ? "成功" : "失败"), ftpFileName);
            return success;
        } catch (Exception e) {
            log.error("{}上传失败{}", ftpFileName, e.getMessage());
            return false;
        } finally {

            this.ftpClientFactory.disconnect(remoteFTPClient);
        }
    }


    public boolean uploadFTPFile2Remote(String remoteFileName, String localFTPFileName) {
        InputStream inputStream = null;
        SSLSessionReuseFTPSClient localClient = null;

        try {
            localClient = getSslSessionReuseFTPSClient();
            inputStream = localClient.retrieveFileStream(convert2FTPCharset(localFTPFileName));
            if (inputStream == null) {
                log.error("读取FTP文件{}失败", localFTPFileName);
                return false;
            }

            return uploadToRemoteFTP(remoteFileName, inputStream);
        } catch (Exception e) {
            log.error("读取FTP文件失败", e);
            return false;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                log.error("FTP连接或文件流关闭异常", e);
            }
        }
    }

    public void downFileFromFtp(String localPath, String ftpPath, String fileName, String type) {
        log.info("ftp downLoadFile ftpByte,localPath:{},ftpPath:{},fileName:{} type:{}", new Object[]{localPath, ftpPath, fileName, type});
        if (StringUtils.isEmpty(ftpPath)) {
            log.info("=========ftp图片路径为空{}", ftpPath);

            return;
        }
        String parentPath = localPath + File.separator;
        FileOutputStream fileOutputStream = null;
        try {
            File file = new File(parentPath);
            if (!file.exists()) {
                FileUtil.mkdir(file);
            }
            log.info("==========开始下载原图==============");
            String newfileName = parentPath + fileName;
            byte[] ftpFileByte = getFtpFileByte(ftpPath);
            if (Objects.nonNull(ftpFileByte) && ftpFileByte.length > 0) {
                File newFile = new File(newfileName);
                log.info("====" + newFile.length());
                fileOutputStream = new FileOutputStream(newFile);
                fileOutputStream.write(ftpFileByte);
            }
            log.info("==========开始下载原图对应的缩略图==============");
            String[] split = ftpPath.split("\\.");
            String filePathSmall = split[0] + "_small." + split[1];
            String smallFileName = filePathSmall.substring(filePathSmall.lastIndexOf("/") + 1);
            byte[] smallftpFileByte = getFtpFileByte(filePathSmall);
            if (Objects.nonNull(smallftpFileByte) && smallftpFileByte.length > 0) {
                File newFile = new File(parentPath + File.separator + smallFileName);
                fileOutputStream = new FileOutputStream(newFile);
                fileOutputStream.write(smallftpFileByte);
                fileOutputStream.close();
            }
        } catch (Exception e) {
            log.error("===生成图片出错", e);
        } finally {
            if (!Objects.isNull(fileOutputStream)) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public boolean uploadMeasurePointFile(String ftpFileName, String localFileName) {
        boolean success = false;
        BufferedInputStream inputStream = null;
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpFileName);
            File localFile = new File(localFileName);
            inputStream = new BufferedInputStream(new FileInputStream(localFile));
            log.info(localFile.getName() + "开始上传.....");

            log.info("FTP的工作目录为---------:" + sslSessionReuseFTPSClient.printWorkingDirectory());
            success = sslSessionReuseFTPSClient.storeFile(convert2FTPCharset(ftpFileName.substring(ftpFileName.lastIndexOf("/") + 1)), inputStream);
            if (success == true) {
                log.info(localFile.getName() + "上传成功");
            } else {
                log.info(localFile.getName() + "上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("------------上传失败" + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            returnClient(sslSessionReuseFTPSClient);
        }
        return success;
    }


    public boolean downLoadFileFromRemoteFtp(String localPath, String ftpPath, String fileName) {
        log.info("ftp downLoadFile start,localPath:{},ftpPath:{},fileName:{}", new Object[]{localPath, ftpPath, fileName});
        if (!localPath.endsWith(File.separator)) {
            localPath = localPath + File.separator;
        }
        if (!ftpPath.startsWith(File.separator)) {
            ftpPath = File.separator + ftpPath;
        }
        log.info("远程系统FTP的工作目录ftpPath为:{}", ftpPath);
        File localFileDir = new File(localPath);
        if (!localFileDir.exists() || !localFileDir.isDirectory()) {
            localFileDir.mkdirs();
        }

        File localFile = new File(localPath + fileName);
        SSLSessionReuseFTPSClient remoteFTPClient = null;
        try (OutputStream is = Files.newOutputStream(localFile.toPath(), new java.nio.file.OpenOption[0])) {
            remoteFTPClient = this.ftpClientFactory.createRemoteFTPClient();
            if (remoteFTPClient == null) {
                throw new RuntimeException("ftp downLoadFile fail,ftp连接失败");
            }
            remoteFTPClient.changeWorkingDirectory(ftpPath);
            log.info("远程系统FTP的工作目录为{}", remoteFTPClient.printWorkingDirectory());
            remoteFTPClient.retrieveFile(fileName, is);
            returnClient(remoteFTPClient);
            return true;
        } catch (Exception e) {
            try {
                remoteFTPClient.disconnect();
            } catch (IOException ex) {
                log.error("sslSessionReuseFTPSClient close ", ex);
            }
            log.error("ftp downLoadFile fail,localPath:{},ftpPath:{},fileName:{},message:{}", new Object[]{localPath, ftpPath, fileName, e.getMessage()});
            return false;
        }
    }


    public boolean uploadStreamToFtp(String ftpFileName, byte[] bytes) {
        boolean success = false;
        InputStream inputStream = new ByteArrayInputStream(bytes);
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpFileName);

            log.info("FTP的工作目录为---------:" + sslSessionReuseFTPSClient.printWorkingDirectory());
            success = sslSessionReuseFTPSClient.storeFile(convert2FTPCharset(ftpFileName.substring(ftpFileName.lastIndexOf("/") + 1)), inputStream);
            if (success == true) {
                log.info("上传成功");
            } else {
                log.info("上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("------------上传失败" + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            returnClient(sslSessionReuseFTPSClient);
        }
        return success;
    }


    public void uploadStardandPointFile(Map<String, List<PictureData>> pictureMap) {
        SSLSessionReuseFTPSClient sslSessionReuseFTPSClient = null;
        try {
            sslSessionReuseFTPSClient = getSslSessionReuseFTPSClient();


            String ftpFilePath = "standardPoint" + "/" + LocalDateTime.now().getYear() + "/" + LocalDateTime.now().getMonth().getValue() + "/" + LocalDateTime.now().getDayOfMonth() + "/";
            changeWorkingDirectory(sslSessionReuseFTPSClient, ftpFilePath);
            for (String key : pictureMap.keySet()) {
                List<PictureData> pictureList = pictureMap.get(key);
                if (CollectionUtils.isNotEmpty(pictureList)) {
                    int size = pictureList.size();
                    for (int i = 0; i < size; i++) {
                        String localFileName = ftpFilePath + key + i + "." + ((PictureData) pictureList.get(i)).suggestFileExtension();
                        File localFile = new File(localFileName);
                        InputStream inputStream = new ByteArrayInputStream(((PictureData) pictureList.get(i)).getData());
                        try {
                            log.info("FTP的工作目录为---------:" + sslSessionReuseFTPSClient.printWorkingDirectory());
                            log.info(localFile.getName() + "开始上传.....");
                            boolean success = sslSessionReuseFTPSClient.storeFile(convert2FTPCharset(localFileName.substring(localFileName.lastIndexOf("/") + 1)), inputStream);
                            if (success == true) {
                                log.info("上传成功");
                            } else {
                                log.info("上传失败");
                            }
                        } catch (Exception e) {
                            log.info(localFile.getName() + "上传失败：" + e.getMessage());
                            if (null != inputStream) {
                                inputStream.close();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("------------上传失败" + e.getMessage());
        } finally {
            returnClient(sslSessionReuseFTPSClient);
        }
    }
}
 